bitkeeper revision 1.921.1.1 (40dab1f9AV7eQ2rrrWjdce8ozia3XQ)
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Thu, 24 Jun 2004 10:50:33 +0000 (10:50 +0000)
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Thu, 24 Jun 2004 10:50:33 +0000 (10:50 +0000)
add more stats collection to migration, prepare for NGIO fixup.

tools/xc/lib/xc.h
tools/xc/lib/xc_domain.c
tools/xc/lib/xc_linux_save.c
tools/xc/py/Xc.c
xen/common/shadow.c
xen/drivers/block/xen_block.c
xen/include/asm-i386/processor.h
xen/include/hypervisor-ifs/dom0_ops.h
xen/include/xen/shadow.h
xen/net/dev.c

index 3423c4ec4610c015102b38fb53dd2c04bfbbb4d8..b2c20eb1222e963134a83da96825b23630e23286 100644 (file)
@@ -35,6 +35,14 @@ typedef struct {
     unsigned long max_memkb;
 } xc_dominfo_t;
 
+typedef struct xc_shadow_control_stats_st
+{
+    unsigned long fault_count;
+    unsigned long dirty_count;
+    unsigned long dirty_net_count;     
+    unsigned long dirty_block_count;     
+} xc_shadow_control_stats_t;
+
 int xc_domain_create(int xc_handle, 
                      unsigned int mem_kb, 
                      const char *name,
@@ -60,8 +68,7 @@ int xc_shadow_control(int xc_handle,
                       unsigned int sop,
                      unsigned long *dirty_bitmap,
                      unsigned long pages,
-                     unsigned long *fault_count,
-                     unsigned long *dirty_count);
+                     xc_shadow_control_stats_t *stats);
 
 
 #define XCFLAGS_VERBOSE 1
index dd8b4ec35ffd1d223afd7848c32795a5ffaa9423..d8ec3e167739c7b699766a89c4c43f5b48ef216d 100644 (file)
@@ -113,8 +113,7 @@ int xc_shadow_control(int xc_handle,
                       unsigned int sop,
                      unsigned long *dirty_bitmap,
                      unsigned long pages,
-                     unsigned long *fault_count,
-                     unsigned long *dirty_count)
+                     xc_shadow_control_stats_t *stats )
 {
     int rc;
     dom0_op_t op;
@@ -126,8 +125,8 @@ int xc_shadow_control(int xc_handle,
 
     rc = do_dom0_op(xc_handle, &op);
 
-    if(fault_count) *fault_count = op.u.shadow_control.fault_count;
-    if(dirty_count) *dirty_count = op.u.shadow_control.dirty_count;
+    if(stats) memcpy(stats, &op.u.shadow_control.stats,
+                    sizeof(xc_shadow_control_stats_t));
 
     if ( rc == 0 )
        return op.u.shadow_control.pages;
index 4913a8527f377e51e778d4b4c7fbcad147a29e15..97ad5fdb4ab379ee3384bdfd3069d5d702872e07 100644 (file)
@@ -144,14 +144,22 @@ static long long tv_to_us( struct timeval *new )
     return (new->tv_sec * 1000000) + new->tv_usec;
 }
 
-static long long tvdelta( struct timeval *new, struct timeval *old )
+static long long llgettimeofday()
+{
+    struct timeval now;
+    gettimeofday(&now, NULL);
+    return tv_to_us(&now);
+}
+
+static long long tv_delta( struct timeval *new, struct timeval *old )
 {
     return ((new->tv_sec - old->tv_sec)*1000000 ) + 
        (new->tv_usec - old->tv_usec);
 }
 
-static int track_cpu_usage( int xc_handle, u64 domid, int faults,
-                           int pages_sent, int pages_dirtied, int print )
+static int print_stats( int xc_handle, u64 domid, 
+                       int pages_sent, xc_shadow_control_stats_t *stats,
+                       int print )
 {
     static struct timeval wall_last;
     static long long      d0_cpu_last;
@@ -162,7 +170,6 @@ static int track_cpu_usage( int xc_handle, u64 domid, int faults,
     long long             d0_cpu_now, d0_cpu_delta;
     long long             d1_cpu_now, d1_cpu_delta;
 
-
     gettimeofday(&wall_now, NULL);
 
     d0_cpu_now = xc_domain_get_cpu_usage( xc_handle, 0 )/1000;
@@ -173,7 +180,7 @@ static int track_cpu_usage( int xc_handle, u64 domid, int faults,
        printf("ARRHHH!!\n");
     }
 
-    wall_delta = tvdelta(&wall_now,&wall_last)/1000;
+    wall_delta = tv_delta(&wall_now,&wall_last)/1000;
 
     if ( wall_delta == 0 ) wall_delta = 1;
 
@@ -186,7 +193,7 @@ static int track_cpu_usage( int xc_handle, u64 domid, int faults,
               (int)((d0_cpu_delta*100)/wall_delta),
               (int)((d1_cpu_delta*100)/wall_delta),
               (int)((pages_sent*PAGE_SIZE*8)/(wall_delta*1000)),
-              (int)((pages_dirtied*PAGE_SIZE*8)/(wall_delta*1000))
+              (int)((stats->dirty_count*PAGE_SIZE*8)/(wall_delta*1000))
            );
 
     d0_cpu_last  = d0_cpu_now;
@@ -197,6 +204,44 @@ static int track_cpu_usage( int xc_handle, u64 domid, int faults,
 }
 
 
+static int analysis_phase( int xc_handle, u64 domid, 
+                          int nr_pfns, unsigned long *arr )
+{
+    long long start, now;
+    xc_shadow_control_stats_t stats;
+
+    start = llgettimeofday();
+
+    while(0)
+    {
+       int i;
+
+       xc_shadow_control( xc_handle, domid, 
+                          DOM0_SHADOW_CONTROL_OP_CLEAN2,
+                          arr, nr_pfns, NULL);
+       printf("#Flush\n");
+       for(i=0;i<100;i++)
+       {           
+           usleep(10000);          
+           now = llgettimeofday();
+           xc_shadow_control( xc_handle, domid, 
+                              DOM0_SHADOW_CONTROL_OP_PEEK,
+                              NULL, 0, &stats);
+
+           printf("now= %lld faults= %ld dirty= %ld dirty_net= %ld dirty_block= %ld\n", 
+                  ((now-start)+500)/1000, 
+                  stats.fault_count, stats.dirty_count,
+                  stats.dirty_net_count, stats.dirty_block_count );
+
+       }
+
+
+    }
+    
+
+    return -1;
+}
+
 int xc_linux_save(int xc_handle,
                   u64 domid, 
                  unsigned int flags,
@@ -210,7 +255,6 @@ int xc_linux_save(int xc_handle,
     int live = flags & XCFLAGS_LIVE;
     int debug = flags & XCFLAGS_DEBUG;
     int sent_last_iter, sent_this_iter, skip_this_iter;
-    unsigned long dirtied_this_iter, faults_this_iter;
 
     /* Important tuning parameters */
     int max_iters  = 29; // limit us to 30 times round loop
@@ -261,6 +305,8 @@ int xc_linux_save(int xc_handle,
        - to skip this iteration because already dirty;
        - to fixup by sending at the end if not already resent; */
     unsigned long *to_send, *to_skip, *to_fix;
+    
+    xc_shadow_control_stats_t stats;
 
     int needed_to_fix = 0;
     int total_sent    = 0;
@@ -374,7 +420,7 @@ int xc_linux_save(int xc_handle,
     { 
        if ( xc_shadow_control( xc_handle, domid, 
                           DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY,
-                          NULL, 0, NULL, NULL ) < 0 )
+                          NULL, 0, NULL ) < 0 )
        {
            ERROR("Couldn't enable shadow mode");
            goto out;
@@ -392,6 +438,9 @@ int xc_linux_save(int xc_handle,
     else
        last_iter = 1;
 
+    /* calculate the power of 2 order of nr_pfns, e.g.
+     15->4 16->4 17->5 */
+    for( i=nr_pfns-1, order_nr=0; i ; i>>=1, order_nr++ );
 
     /* Setup to_send bitmap */
     {
@@ -425,11 +474,7 @@ int xc_linux_save(int xc_handle,
 
     }
 
-    /* calculate the power of 2 order of nr_pfns, e.g.
-     15->4 16->4 17->5 */
-    for( i=nr_pfns-1, order_nr=0; i ; i>>=1, order_nr++ );
-
-printf("nr_pfns=%d order_nr=%d\n",nr_pfns, order_nr);
+    analysis_phase( xc_handle, domid, nr_pfns, to_skip );
 
     /* We want zeroed memory so use calloc rather than malloc. */
     pfn_type = calloc(BATCH_SIZE, sizeof(unsigned long));
@@ -484,7 +529,7 @@ printf("nr_pfns=%d order_nr=%d\n",nr_pfns, order_nr);
         goto out;
     }
 
-    track_cpu_usage( xc_handle, domid, 0, 0, 0, 0 );
+    print_stats( xc_handle, domid, 0, &stats, 0 );
 
     /* Now write out each data page, canonicalising page tables as we go... */
     
@@ -516,7 +561,7 @@ printf("nr_pfns=%d order_nr=%d\n",nr_pfns, order_nr);
            if ( !last_iter && 
                 xc_shadow_control(xc_handle, domid, 
                                   DOM0_SHADOW_CONTROL_OP_PEEK,
-                                  to_skip, nr_pfns, NULL, NULL) != nr_pfns ) 
+                                  to_skip, nr_pfns, NULL) != nr_pfns ) 
            {
                ERROR("Error peeking shadow bitmap");
                goto out;
@@ -722,7 +767,7 @@ printf("nr_pfns=%d order_nr=%d\n",nr_pfns, order_nr);
 
        if ( last_iter )
        {
-           track_cpu_usage( xc_handle, domid, 0, sent_this_iter, 0, 1);
+           print_stats( xc_handle, domid, sent_this_iter, &stats, 1);
 
            verbose_printf("Total pages sent= %d (%.2fx)\n", 
                           total_sent, ((float)total_sent)/nr_pfns );
@@ -732,7 +777,7 @@ printf("nr_pfns=%d order_nr=%d\n",nr_pfns, order_nr);
        if ( debug && last_iter )
        {
            int minusone = -1;
-           memset( to_send, 0xff, nr_pfns/8 );
+           memset( to_send, 0xff, (nr_pfns+8)/8 );
            debug = 0;
            printf("Entering debug resend-all mode\n");
     
@@ -766,8 +811,7 @@ printf("nr_pfns=%d order_nr=%d\n",nr_pfns, order_nr);
 
            if ( xc_shadow_control( xc_handle, domid, 
                                    DOM0_SHADOW_CONTROL_OP_CLEAN2,
-                                   to_send, nr_pfns, &faults_this_iter,
-                                   &dirtied_this_iter) != nr_pfns ) 
+                                   to_send, nr_pfns, &stats ) != nr_pfns ) 
            {
                ERROR("Error flushing shadow PT");
                goto out;
@@ -775,9 +819,7 @@ printf("nr_pfns=%d order_nr=%d\n",nr_pfns, order_nr);
 
            sent_last_iter = sent_this_iter;
 
-           //dirtied_this_iter = count_bits( nr_pfns, to_send ); 
-           track_cpu_usage( xc_handle, domid, faults_this_iter,
-                            sent_this_iter, dirtied_this_iter, 1);
+           print_stats( xc_handle, domid, sent_this_iter, &stats, 1);
            
        }
 
index d2a291e4c85f6b1a9d25461b84b577ec0d445eeb..1455096686b277a2f9d4e22b16eaeed71271ec2f 100644 (file)
@@ -1296,7 +1296,7 @@ static PyObject *pyxc_shadow_control(PyObject *self,
                                       &dom, &op) )
         return NULL;
 
-    if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, NULL) < 0 )
+    if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL) < 0 )
         return PyErr_SetFromErrno(xc_error);
     
     Py_INCREF(zero);
index d9e4d9aef81d0e89c9c44b5744102be770845791..63280ba2a0600a5cc2c4af943bf42b9384f32d27 100644 (file)
@@ -48,7 +48,7 @@ fault handler spinning waiting to grab the shadow lock. It may have
 intterupts disabled, hence we can't use the normal flush_tlb_cpu
 mechanism.
 
-For the moment, we have a grim hace whereby the spinlock in the shadow
+For the moment, we have a grim race whereby the spinlock in the shadow
 fault handler is actually a try lock, in a loop with a helper for the
 tlb flush code.
 
@@ -379,6 +379,17 @@ static int shadow_mode_table_op( struct task_struct *p,
                __scan_shadow_table( m, TABLE_OP_FREE_L1 );
                
        send_bitmap:
+               sc->stats.fault_count       = p->mm.shadow_fault_count;
+               sc->stats.dirty_count       = p->mm.shadow_dirty_count;
+               sc->stats.dirty_net_count   = p->mm.shadow_dirty_net_count;
+               sc->stats.dirty_block_count = p->mm.shadow_dirty_block_count;
+
+               p->mm.shadow_fault_count       = 0;
+               p->mm.shadow_dirty_count       = 0;
+               p->mm.shadow_dirty_net_count   = 0;
+               p->mm.shadow_dirty_block_count = 0;
+       
+               sc->pages = p->tot_pages;
 
                if( p->tot_pages > sc->pages || 
                        !sc->dirty_bitmap || !p->mm.shadow_dirty_bitmap )
@@ -387,12 +398,6 @@ static int shadow_mode_table_op( struct task_struct *p,
                        goto out;
                }
 
-               sc->fault_count = p->mm.shadow_fault_count;
-               sc->dirty_count = p->mm.shadow_dirty_count;
-               p->mm.shadow_fault_count = 0;
-               p->mm.shadow_dirty_count = 0;
-       
-               sc->pages = p->tot_pages;
        
 #define chunk (8*1024) // do this in 1KB chunks for L1 cache
        
@@ -428,6 +433,11 @@ static int shadow_mode_table_op( struct task_struct *p,
     case DOM0_SHADOW_CONTROL_OP_PEEK:
     {
                int i;
+
+               sc->stats.fault_count       = p->mm.shadow_fault_count;
+               sc->stats.dirty_count       = p->mm.shadow_dirty_count;
+               sc->stats.dirty_net_count   = p->mm.shadow_dirty_net_count;
+               sc->stats.dirty_block_count = p->mm.shadow_dirty_block_count;
        
                if( p->tot_pages > sc->pages || 
                        !sc->dirty_bitmap || !p->mm.shadow_dirty_bitmap )
@@ -724,7 +734,7 @@ int shadow_fault( unsigned long va, long error_code )
             int i;
             sl1pfn_info = alloc_shadow_page( &current->mm ); 
             sl1pfn_info->type_and_flags = PGT_l1_page_table;
-
+                       
             sl1pfn = sl1pfn_info - frame_table;
 
             SH_VVLOG("4a: l1 not shadowed ( %08lx )",sl1pfn);
index 6901262cb8fd14b8a711d02e9ff773946a473e00..0f80501b831d224e9a433217e6e8f1ae28f47dd4 100644 (file)
@@ -364,7 +364,8 @@ static void unlock_buffer(unsigned long buffer,
        struct task_struct *p = frame_table[pfn].u.domain;
 
        if( p->mm.shadow_mode == SHM_logdirty )
-           mark_dirty( &p->mm, pfn );  
+           if( mark_dirty( &p->mm, pfn ) )
+               p->mm.shadow_dirty_block_count++;
 
 
         if ( writeable_buffer )
index b1eab99d5663a047a6b25ee312283bde0879feed..5edc743edacebf0a1d05940dad3b53b884f7d5b1 100644 (file)
@@ -465,6 +465,8 @@ struct mm_struct {
     unsigned int shadow_page_count;     
     unsigned int shadow_fault_count;     
     unsigned int shadow_dirty_count;     
+    unsigned int shadow_dirty_net_count;     
+    unsigned int shadow_dirty_block_count;     
 
 
     /* Current LDT details. */
index 6273878d16ba3a37dcab85df9176f365c0a32efd..effb7d128727303926cf639c5112dedcdc1dd405 100644 (file)
@@ -245,10 +245,20 @@ typedef struct dom0_sched_id_st
 #define DOM0_SHADOW_CONTROL_OP_OFF         0
 #define DOM0_SHADOW_CONTROL_OP_ENABLE_TEST 1
 #define DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY 2
+#define DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE 3
 #define DOM0_SHADOW_CONTROL_OP_FLUSH       10     /* table ops */
 #define DOM0_SHADOW_CONTROL_OP_CLEAN       11
 #define DOM0_SHADOW_CONTROL_OP_PEEK        12
 #define DOM0_SHADOW_CONTROL_OP_CLEAN2      13
+
+typedef struct dom0_shadow_control_stats_st
+{
+    unsigned long fault_count;
+    unsigned long dirty_count;
+    unsigned long dirty_net_count;     
+    unsigned long dirty_block_count;     
+} dom0_shadow_control_stats_t;
+
 typedef struct dom0_shadow_control_st
 {
     /* IN variables. */
@@ -258,8 +268,7 @@ typedef struct dom0_shadow_control_st
     /* IN/OUT variables */
     unsigned long  pages;  // size of buffer, updated with actual size
     /* OUT varaibles */
-    unsigned long fault_count;
-    unsigned long dirty_count;
+    dom0_shadow_control_stats_t stats;
 } dom0_shadow_control_t;
 
 #define DOM0_SETDOMAINNAME     26
index 1597e1feb2190d7296c1b8d14cc48a59da17a837..83dc29f00dda15f149aa64248ccbbeaa308067a7 100644 (file)
@@ -17,8 +17,9 @@
 /* Shadow PT operation mode : shadowmode variable in mm_struct */
 #define SHM_test        (1) /* just run domain on shadow PTs */
 #define SHM_logdirty    (2) /* log pages that are dirtied */
-#define SHM_cow         (3) /* copy on write all dirtied pages */
-#define SHM_translate   (4) /* lookup machine pages in translation table */
+#define SHM_translate   (3) /* lookup machine pages in translation table */
+//#define SHM_cow       (4) /* copy on write all dirtied pages */
+
 
 #define shadow_linear_pg_table ((l1_pgentry_t *)SH_LINEAR_PT_VIRT_START)
 #define shadow_linear_l2_table ((l2_pgentry_t *)(SH_LINEAR_PT_VIRT_START+(SH_LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
@@ -76,9 +77,10 @@ printk("DOM%lld: (file=shadow.c, line=%d) " _f "\n", \
 
 /************************************************************************/
 
-    static inline void __mark_dirty( struct mm_struct *m, unsigned int mfn )
+static inline int __mark_dirty( struct mm_struct *m, unsigned int mfn )
 {
     unsigned int pfn;
+    int rc = 0;
 
     ASSERT(spin_is_locked(&m->shadow_lock));
        
@@ -90,17 +92,19 @@ printk("DOM%lld: (file=shadow.c, line=%d) " _f "\n", \
        really part of the domain's psuedo-physical memory map e.g.
        the shared info frame. Nothing to do here...
        */
-    if ( unlikely(pfn & 0x80000000U) ) return; 
+    if ( unlikely(pfn & 0x80000000U) ) return rc
 
     ASSERT(m->shadow_dirty_bitmap);
     if( likely(pfn<m->shadow_dirty_bitmap_size) )
     {
-               /* These updates occur with mm.shadow_lock held, so use 
-                  (__) version of test_and_set */
-               if( ! __test_and_set_bit( pfn, m->shadow_dirty_bitmap ) )
-               {
-                       m->shadow_dirty_count++;
-               }
+       /* These updates occur with mm.shadow_lock held, so use 
+          (__) version of test_and_set */
+       if( __test_and_set_bit( pfn, m->shadow_dirty_bitmap ) == 0 )
+       {
+           // if we set it
+           m->shadow_dirty_count++;
+           rc = 1;
+       }
     }
     else
     {
@@ -113,17 +117,20 @@ printk("DOM%lld: (file=shadow.c, line=%d) " _f "\n", \
               frame_table[mfn].type_and_flags );
        //show_traceX();
     }
-
+       
+    return rc;
 }
 
 
-static inline void mark_dirty( struct mm_struct *m, unsigned int mfn )
+static inline int mark_dirty( struct mm_struct *m, unsigned int mfn )
 {      
+       int rc;
     ASSERT(local_irq_is_enabled());
     //if(spin_is_locked(&m->shadow_lock)) printk("+");
     spin_lock(&m->shadow_lock);
-    __mark_dirty( m, mfn );
+    rc = __mark_dirty( m, mfn );
     spin_unlock(&m->shadow_lock);
+       return rc;
 }
 
 
index 909e586b53df46ec2728e040e68114f3e955c28b..4a3088e1bfc1e05ba2ce15f38d8318c93aa31dfe 100644 (file)
@@ -567,7 +567,10 @@ void deliver_packet(struct sk_buff *skb, net_vif_t *vif)
 
     /* if in shadow mode, mark the buffer as dirty */
     if( p->mm.shadow_mode == SHM_logdirty )
-       mark_dirty( &p->mm, (new_page-frame_table) );
+    {
+       if( mark_dirty( &p->mm, (new_page-frame_table) ) )
+           p->mm.shadow_dirty_net_count++;
+    }
 
     /* Updates must happen before releasing the descriptor. */
     smp_wmb();
@@ -2269,16 +2272,6 @@ long flush_bufs_for_vif(net_vif_t *vif)
        if( p->mm.shadow_mode == SHM_logdirty )
        {
            mark_dirty( &p->mm, rx->pte_ptr>>PAGE_SHIFT );
-#if 0
-           mark_dirty( &p->mm, rx->buf_pfn ); // XXXXXXX debug
-
-           {
-               unsigned long * p = map_domain_mem( rx->buf_pfn<<PAGE_SHIFT );
-               p[2] = 0xdeadc001;
-               unmap_domain_mem(p);
-           }
-#endif
-
        }
        /* assume the shadow page table is about to be blown away,
           and that its not worth marking the buffer as dirty */